/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.treepoke.util.criptografia;

import com.treepoke.util.exception.UtilException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 *
 * @author dpulido
 */
public class Criptografia {
    
    //algoritmos
    public static String MD2 = "MD2";
    public static String MD5 = "MD5";
    public static String SHA1 = "SHA-1";
    public static String SHA256 = "SHA-256";
    public static String SHA384 = "SHA-384";
    public static String SHA512 = "SHA-512";
    
    private static byte[] key = {
        0x21, 0x68, 0x32, 0x77, 0x49, 0x45, 0x41, 0x10, 0x65, 0x47, 0x72, 0x26, 0x74, 0x2a, 0x65, 0x79
    };    
    
    /**
     * *
     * Encripta un mensaje de texto mediante algoritmo de resumen de mensaje.
     * Y le concatena el algorithm
     *
     * @param message texto a encriptar
     * @param algorithm algoritmo de encriptacion, puede ser: MD2, MD5, SHA-1,
     * SHA-256, SHA-384, SHA-512
     * @return mensaje encriptado
     */
    public static String getStringMessageDigestAlgorithm(final String password, final String algorithm) {
        String base64;
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            digest.update(password.getBytes());
            base64 = new BASE64Encoder().encode(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return "{"+(algorithm.equals(Criptografia.SHA1)?"SHA":algorithm)+"}" + base64;
    }
    
    /**
     * *
     * Encripta un mensaje de texto mediante algoritmo de resumen de mensaje.
     *
     * @param message texto a encriptar
     * @param algorithm algoritmo de encriptacion, puede ser: MD2, MD5, SHA-1,
     * SHA-256, SHA-384, SHA-512
     * @return mensaje encriptado
     */
    public static String getStringMessageDigest(final String password, final String algorithm) {
        String base64;
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            digest.update(password.getBytes());
            base64 = new BASE64Encoder().encode(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return base64;
    }
    
    /**
     * Tomado de
     * http://techie-experience.blogspot.com/2012/10/encryption-and-decryption-using-aes.html
     *
     * @param strToEncrypt
     * @return
     */
    public static String encrypt(String strToEncrypt, byte[] key) throws UtilException {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return new BASE64Encoder().encodeBuffer(cipher.doFinal(strToEncrypt.getBytes()));
        } catch (IllegalBlockSizeException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (BadPaddingException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (InvalidKeyException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (NoSuchAlgorithmException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (NoSuchPaddingException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        }
    }
    
    public static String encrypt(String strToEncrypt) throws UtilException {
        return encrypt(strToEncrypt, key);
    }    

    /**
     * Tomado de
     * http://techie-experience.blogspot.com/2012/10/encryption-and-decryption-using-aes.html
     *
     * @param strToDecrypt
     * @return
     */
    public static String decrypt(String strToDecrypt, byte[] key) throws UtilException {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return new String(cipher.doFinal(new BASE64Decoder().decodeBuffer(strToDecrypt)));
        } catch (IOException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (IllegalBlockSizeException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (BadPaddingException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (InvalidKeyException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (NoSuchAlgorithmException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        } catch (NoSuchPaddingException ex) {
            throw new UtilException(ex.getMessage(), ex, 0);
        }
    }
    
    public static String decrypt(String strToDecrypt) throws UtilException {
        return decrypt(strToDecrypt, key);
    }
    
    
}

